
/*
 * 
 * Segmented PictureReader.java
 * David Ing
 * 
 * Reads segmented images from Image team.  Finds all the different
 * colors and adds them into an array list.
 * 
 * Gives each of the different colors a name.
 * 
 * The program accepts an x and a y location and prints out the color
 * are that x y location
 * 
 * X,Y, and picture can be chosen from the commandline or at run time
 * Plays associated sound files
 * ----------------------------------------------------------------------------
 */

import java.awt.Color;
import java.util.ArrayList;
import java.util.Scanner;

public class DistanceTransformReader{
    
    // offsets for command line inputs
    public static final int X_OFFSET = 0;   // index for x coordinates
    public static final int Y_OFFSET = 1;   // index for y coordinates
    public static final int PIC_OFFSET = 2; // index for picture file's path

    public static final int DEAD_SPACE = 3; // seconds of deadspace played
    private int numColors;                  // number of colors in the picture
    static Picture pic;                     // segmented picture chosen by user
    static ArrayList<Color> colors;         // list of the different colors
    
/*-------------------------------------------------------------------------
 * SegmentedPictureReader
 * 
 * default constructor for Segmented Picture Reader
 * sets all fields to 0
 * 
 -------------------------------------------------------------------------*/
    public DistanceTransformReader(){
        // initializes number of colors
        numColors = 0;
        // creates new array for colors with initial capacity 0
        colors = new ArrayList<Color>(0);
    }

    
/*-------------------------------------------------------------------------
 * ReadPic(Picture pic)
 * 
 * Takes in segmented picture from user and assigns it to pic
 * calls findcolor to get an arrayList of all the different colors.
 * 
 * Returns true if successful, false if failure
 * 
 -------------------------------------------------------------------------*/
    public boolean readPic(Picture pic){
        // returns false if the picture does not exist
        if(pic.getFileName() == null){
            System.err.println("PICTURE DOES NOT EXIST!!!");
            return false;
        }
        
        // call find colors to find all the different colors in this picture
        colors = findColors(pic);
        
        return true;
    }
    
/*-------------------------------------------------------------------------
 * findColors(Picture pic)
 * 
 * Takes in a picture, finds all the different colors while incrementing
 * the color count.  Returns an ArrayList of colors.
 -------------------------------------------------------------------------*/
    public ArrayList<Color> findColors(Picture pic){
        // create array of all the pixels in the picture
        Pixel[] pixels = pic.getPixels();
        
        // loops through all the pixels
        for(int i = 0; i < pixels.length; i++){
            // checks if current pixel's color is already in the color array
            if(!colors.contains( pixels[i].getColor() )){
                colors.add(pixels[i].getColor());
                numColors++;
            }
        }
        
        return colors;
    }
    
/*-------------------------------------------------------------------------
 * playSoundRegion(Color ccc, String pictureName)
 * 
 * Takes in a color and plays the appropriate sound from the file according
 * to the given color region.  Sound file should be IN THE SAME FILE AS
 * THE PICTURE and in the following format:
 * 
 * FORMAT:  <pictureName>.<RED>.<GREEN>.<BLUE>.wav
 * 
 * No return value
 * 
 --------------------------------------------------------------------------*/
    public static void playSoundRegion(Color ccc, String pictureName) {
        // make a sound file to play, default sound is dead silence
        Sound soundFile = new Sound(DEAD_SPACE);
        // name of the tone for distance Transform
        String toneName = "/Users/daviding/000GroziTest/DistanceTest/tone.wav";

        // if the color is not black, load sound file
        if(!(ccc.getRed() == 0 && ccc.getGreen() == 0 && ccc.getBlue() == 0)){
            // get tone sound
            try {
                soundFile.loadFromFile(toneName);
        
            // prints error if file not found
            } catch (SoundException e) {
                System.err.println("ERROR: SOUND FILE DOES NOT EXIST!!!");
            }
        }

        soundFile.adjustVolume(ccc.getRed());
        
        /*
         * LINE 142: Uncomment to see the frequency waves of soundfiles
         */
        
        // explores the sound
        //soundFile.explore();
        // play sound file
        soundFile.play();
    }
    

/*-------------------------------------------------------------------------
 * findPic
 * 
 * Method that finds the picture based on whether or not the path is given
 * If the picutre filepath is given then it will follow that path and open
 * the given picture. Otherwise the program will use filechooser to have the
 * user dynamically choose the picture file.
 * 
 -------------------------------------------------------------------------*/
    public static Picture findPic(String picturePath){
        // if picture path is not set
        if(picturePath.length() == 0)
        {
            // choose pic manually
            picturePath = FileChooser.pickAFile();
        }

        // create new picture object based on the given path
        Picture pic = new Picture(picturePath);

        // sends back the picture
        return pic;
    }
 
/*-------------------------------------------------------------------------
 * getXY
 *
 * Method that takes in xy from user if no command line arguments to
 * specify xy
 * 
 * Program loops until user calls ^D
 *
 * input =  variables to store xy coordinates
 * output = x and y are set to the coo
 -------------------------------------------------------------------------*/
    public static void getXY(Pixel[] pixels){
        // Color of pixel user chooses
        Color ccc;
        // x and y inputs for the picture from user
        int x,y;
        // Scanner to read input from user
        Scanner scan = new Scanner(System.in);

        // prompts user
        System.out.print("Do you want to check a point? ");
        System.out.println("Any character to continue, EOF to quit)");
        // loop while user has input
        while(scan.hasNext()){
            // throw away the buffer 
            scan.next();
            
            // asks for x/y input
            System.out.print("Enter in some x value:  ");
            x = scan.nextInt();
            System.out.print("Enter in some y value:  ");
            y = scan.nextInt();

            // asign color of the chosen pixel
            ccc = pixels[x + y*pic.getWidth()].getColor();
            // prints out color region
            System.out.println(ccc);
            // plays sound from color region
            playSoundRegion(ccc, pic.getFileName());
        
            // asks to continue
            System.out.print("Do you want to check a point? ");
            System.out.println("Any character to continue, EOF to quit)");
        }
        // closes the java application
        System.exit(0);
    }
/*-------------------------------------------------------------------------
 * main
 * 
 * Main method does the following
 * 1.  Takes in picture file
 * 2.  Reads the segmented picture
 * 3.  accepts x y input and will play appropriate sound file for color
 * 
 -------------------------------------------------------------------------*/
    public static void main(String[] args) throws SoundException{
        // color of the pixel that the user chooses
        Color ccc;
        // x and y inputs for the picture from user
        int x,y;
        // file path for the desired picture
        String picturePath = "";
//String picPath="/Users/daviding/000GroziTest/DistanceTest/test2.bmp";
        
        // Creates default SegmentedPictureReader to read the segmented image
        SegmentedPictureReader seg = new SegmentedPictureReader();

        // if there is a third argument
        if(args.length > PIC_OFFSET){
            // set pic path based on third argument
            picturePath = args[PIC_OFFSET];
        }
        // finds image to process by calling picPath method
        pic = findPic(picturePath);

        // processes the image data
        if(seg.readPic(pic))
        {
            // OPTIONAL EXPLORE METHOD TO SIMULATE USER INTERFACE
            //pic.explore();
            // gets the pixels for the picture
            Pixel[] pixels = pic.getPixels();   

            // if there are command line arguments
            if(args.length > Y_OFFSET){
                // gets xy from command line
                x = Integer.valueOf(args[X_OFFSET]);
                y = Integer.valueOf(args[Y_OFFSET]);

                // asign color of the chosen pixel
                ccc = pixels[x + y*pic.getWidth()].getColor();
                // prints out color region
                System.out.println(ccc);
                // plays sound from color region
                playSoundRegion(ccc, pic.getFileName());

            // prompt to check xy
            }else{
                // call getXY from user
                getXY(pixels);
            }
        }
    }
}


